#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
装饰器模式 (Decorator Pattern) - Python实现详解

概述引导：
装饰器模式动态地给对象添加新功能，而不改变其结构。
对于Java工程师来说，Python的装饰器模式有语言级别的支持，更加强大。

学习要点：
1. 传统装饰器模式实现
2. Python装饰器语法糖
3. 类装饰器和函数装饰器
4. 装饰器链和参数化装饰器

Java对比要点：
- Java需要定义接口和多个装饰器类
- Python有内置的装饰器语法(@decorator)
- Python装饰器更灵活，支持函数和类
- Python可以动态组合装饰器

关键理解：
装饰器模式在Python中有语言级支持，既可以用传统方式也可以用@语法。
"""

from abc import ABC, abstractmethod
from typing import Any, Callable, Dict, List, Optional, Union
from functools import wraps, lru_cache
from datetime import datetime
import time
import json
import logging
from dataclasses import dataclass


# ============= 传统装饰器模式 =============

class Component(ABC):
    """
    组件抽象基类 - 定义接口
    
    Java对比：
    - Java使用interface或abstract class
    - Python的ABC更灵活
    """
    
    @abstractmethod
    def operation(self) -> str:
        """执行操作"""
        pass
    
    @abstractmethod
    def get_cost(self) -> float:
        """获取成本"""
        pass


class ConcreteComponent(Component):
    """
    具体组件 - 基础实现
    
    这是被装饰的基础对象
    """
    
    def __init__(self, name: str, base_cost: float = 10.0):
        self.name = name
        self.base_cost = base_cost
    
    def operation(self) -> str:
        """基础操作"""
        return f"基础组件: {self.name}"
    
    def get_cost(self) -> float:
        """基础成本"""
        return self.base_cost


class Decorator(Component):
    """
    装饰器抽象基类
    
    Java对比：
    - Java需要实现相同的接口
    - Python可以使用组合和继承
    """
    
    def __init__(self, component: Component):
        self._component = component
    
    def operation(self) -> str:
        """委托给被装饰对象"""
        return self._component.operation()
    
    def get_cost(self) -> float:
        """委托成本计算"""
        return self._component.get_cost()


class LoggingDecorator(Decorator):
    """
    日志装饰器 - 添加日志功能
    """
    
    def operation(self) -> str:
        """添加日志功能"""
        result = super().operation()
        log_msg = f"[LOG] 执行操作: {result}"
        print(log_msg)
        return f"{result} + 日志记录"
    
    def get_cost(self) -> float:
        """添加日志成本"""
        return super().get_cost() + 2.0


class EncryptionDecorator(Decorator):
    """
    加密装饰器 - 添加加密功能
    """
    
    def operation(self) -> str:
        """添加加密功能"""
        result = super().operation()
        encrypted = f"[ENCRYPTED]{result}[/ENCRYPTED]"
        return f"{encrypted} + 加密保护"
    
    def get_cost(self) -> float:
        """添加加密成本"""
        return super().get_cost() + 5.0


class CompressionDecorator(Decorator):
    """
    压缩装饰器 - 添加压缩功能
    """
    
    def operation(self) -> str:
        """添加压缩功能"""
        result = super().operation()
        compressed = f"[COMPRESSED]{result}[/COMPRESSED]"
        return f"{compressed} + 数据压缩"
    
    def get_cost(self) -> float:
        """添加压缩成本"""
        return super().get_cost() + 3.0


class CacheDecorator(Decorator):
    """
    缓存装饰器 - 添加缓存功能
    """
    
    def __init__(self, component: Component):
        super().__init__(component)
        self._cache = {}
    
    def operation(self) -> str:
        """添加缓存功能"""
        cache_key = "operation_result"
        if cache_key in self._cache:
            cached_result = self._cache[cache_key]
            return f"{cached_result} + 缓存命中"
        
        result = super().operation()
        self._cache[cache_key] = result
        return f"{result} + 缓存存储"
    
    def get_cost(self) -> float:
        """缓存可能降低成本"""
        return super().get_cost() + 1.0


# ============= Python装饰器语法 =============

def timing_decorator(func: Callable) -> Callable:
    """
    计时装饰器 - Python特色实现
    
    Python优势：
    - 使用@语法更简洁
    - 支持函数装饰
    - 自动包装功能
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"[TIMING] {func.__name__} 执行时间: {execution_time:.4f}秒")
        return result
    return wrapper


def retry_decorator(max_attempts: int = 3, delay: float = 1.0):
    """
    重试装饰器 - 参数化装饰器
    
    Python特色：
    - 支持参数化
    - 可配置行为
    - 闭包实现
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs):
            last_exception = None
            
            for attempt in range(max_attempts):
                try:
                    result = func(*args, **kwargs)
                    if attempt > 0:
                        print(f"[RETRY] {func.__name__} 在第{attempt + 1}次尝试成功")
                    return result
                except Exception as e:
                    last_exception = e
                    if attempt < max_attempts - 1:
                        print(f"[RETRY] {func.__name__} 第{attempt + 1}次尝试失败: {e}")
                        time.sleep(delay)
                    else:
                        print(f"[RETRY] {func.__name__} 所有尝试都失败了")
            
            raise last_exception
        return wrapper
    return decorator


def validation_decorator(validate_func: Callable[[Any], bool]):
    """
    验证装饰器 - 高阶函数装饰器
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 验证参数
            for arg in args:
                if not validate_func(arg):
                    raise ValueError(f"参数验证失败: {arg}")
            
            result = func(*args, **kwargs)
            print(f"[VALIDATION] {func.__name__} 参数验证通过")
            return result
        return wrapper
    return decorator


def memoize_decorator(func: Callable) -> Callable:
    """
    记忆化装饰器 - 缓存函数结果
    
    Python内置了lru_cache，这里展示自定义实现
    """
    cache = {}
    
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 创建缓存键
        key = str(args) + str(sorted(kwargs.items()))
        
        if key in cache:
            print(f"[MEMOIZE] {func.__name__} 缓存命中")
            return cache[key]
        
        result = func(*args, **kwargs)
        cache[key] = result
        print(f"[MEMOIZE] {func.__name__} 结果已缓存")
        return result
    
    return wrapper


# ============= 类装饰器 =============

class CounterDecorator:
    """
    计数器装饰器 - 类装饰器实现
    
    Python特色：
    - 类可以作为装饰器
    - 支持状态保持
    - 更复杂的装饰逻辑
    """
    
    def __init__(self, func: Callable):
        self.func = func
        self.count = 0
        wraps(func)(self)
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"[COUNTER] {self.func.__name__} 被调用第{self.count}次")
        return self.func(*args, **kwargs)
    
    def get_count(self) -> int:
        """获取调用次数"""
        return self.count


class RateLimitDecorator:
    """
    限流装饰器 - 控制调用频率
    """
    
    def __init__(self, max_calls: int, time_window: float):
        self.max_calls = max_calls
        self.time_window = time_window
        self.calls = []
    
    def __call__(self, func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args, **kwargs):
            now = time.time()
            
            # 清理过期的调用记录
            self.calls = [call_time for call_time in self.calls 
                         if now - call_time < self.time_window]
            
            # 检查是否超过限制
            if len(self.calls) >= self.max_calls:
                raise Exception(f"调用频率超限: {self.max_calls}次/{self.time_window}秒")
            
            # 记录本次调用
            self.calls.append(now)
            print(f"[RATE_LIMIT] {func.__name__} 调用通过 ({len(self.calls)}/{self.max_calls})")
            
            return func(*args, **kwargs)
        return wrapper


# ============= 装饰器组合 =============

class DecoratorChain:
    """
    装饰器链 - 组合多个装饰器
    
    Python特色：
    - 动态组合装饰器
    - 可配置装饰器顺序
    - 运行时修改装饰器
    """
    
    def __init__(self):
        self.decorators = []
    
    def add_decorator(self, decorator: Callable) -> 'DecoratorChain':
        """添加装饰器"""
        self.decorators.append(decorator)
        return self
    
    def decorate(self, func: Callable) -> Callable:
        """应用所有装饰器"""
        decorated_func = func
        
        # 从后往前应用装饰器（保持正确的装饰顺序）
        for decorator in reversed(self.decorators):
            decorated_func = decorator(decorated_func)
        
        return decorated_func
    
    def clear(self):
        """清空装饰器链"""
        self.decorators.clear()


# ============= 实际应用示例 =============

@dataclass
class User:
    """用户类 - 用于演示"""
    id: int
    name: str
    email: str
    is_active: bool = True


class UserService:
    """
    用户服务 - 演示装饰器在实际应用中的使用
    """
    
    def __init__(self):
        self.users = {
            1: User(1, "张三", "zhangsan@example.com"),
            2: User(2, "李四", "lisi@example.com"),
            3: User(3, "王五", "wangwu@example.com")
        }
    
    @timing_decorator
    @memoize_decorator
    def get_user(self, user_id: int) -> Optional[User]:
        """获取用户 - 带计时和缓存"""
        # 模拟数据库查询延迟
        time.sleep(0.1)
        return self.users.get(user_id)
    
    @retry_decorator(max_attempts=3, delay=0.5)
    @validation_decorator(lambda x: isinstance(x, int) and x > 0)
    def delete_user(self, user_id: int) -> bool:
        """删除用户 - 带重试和验证"""
        if user_id not in self.users:
            raise ValueError(f"用户不存在: {user_id}")
        
        # 模拟可能失败的操作
        import random
        if random.random() < 0.3:  # 30%的失败率
            raise Exception("数据库连接失败")
        
        del self.users[user_id]
        return True
    
    @CounterDecorator
    def list_users(self) -> List[User]:
        """列出用户 - 带计数器"""
        return list(self.users.values())
    
    @RateLimitDecorator(max_calls=5, time_window=10.0)
    def send_email(self, user_id: int, message: str) -> bool:
        """发送邮件 - 带限流"""
        user = self.users.get(user_id)
        if not user:
            return False
        
        print(f"发送邮件给 {user.name} ({user.email}): {message}")
        return True


# ============= 演示函数 =============

def demonstrate_traditional_decorator():
    """
    演示传统装饰器模式
    
    概述引导：
    展示传统的装饰器模式实现，通过组合的方式
    动态地给对象添加新功能。
    
    学习要点：
    1. 组件和装饰器的接口统一
    2. 装饰器的组合和嵌套
    3. 功能的动态添加
    4. 成本计算的累加
    
    关键理解：
    传统装饰器模式通过对象组合实现功能扩展。
    """
    print("=== 传统装饰器模式演示 ===")
    print("\n学习目标：")
    print("- 理解装饰器模式的结构")
    print("- 掌握装饰器的组合方式")
    print("- 学习功能的动态扩展")
    print("\n重点概念：")
    print("- 组件接口的统一性")
    print("- 装饰器的透明性")
    print("- 功能组合的灵活性")
    print("=" * 50)
    
    # 创建基础组件
    component = ConcreteComponent("数据处理器", 10.0)
    print(f"\n基础组件: {component.operation()}")
    print(f"基础成本: ¥{component.get_cost():.2f}")
    
    # 添加日志装饰器
    logged_component = LoggingDecorator(component)
    print(f"\n添加日志: {logged_component.operation()}")
    print(f"日志成本: ¥{logged_component.get_cost():.2f}")
    
    # 添加加密装饰器
    encrypted_component = EncryptionDecorator(logged_component)
    print(f"\n添加加密: {encrypted_component.operation()}")
    print(f"加密成本: ¥{encrypted_component.get_cost():.2f}")
    
    # 添加压缩装饰器
    compressed_component = CompressionDecorator(encrypted_component)
    print(f"\n添加压缩: {compressed_component.operation()}")
    print(f"压缩成本: ¥{compressed_component.get_cost():.2f}")
    
    # 添加缓存装饰器
    cached_component = CacheDecorator(compressed_component)
    print(f"\n添加缓存: {cached_component.operation()}")
    print(f"缓存成本: ¥{cached_component.get_cost():.2f}")
    
    # 再次调用缓存组件
    print(f"\n再次调用: {cached_component.operation()}")


def demonstrate_python_decorators():
    """
    演示Python装饰器语法
    """
    print("\n=== Python装饰器语法演示 ===")
    
    # 定义测试函数
    @timing_decorator
    @memoize_decorator
    def fibonacci(n: int) -> int:
        """斐波那契数列 - 带计时和记忆化"""
        if n <= 1:
            return n
        return fibonacci(n - 1) + fibonacci(n - 2)
    
    @retry_decorator(max_attempts=3, delay=0.1)
    def unreliable_operation(success_rate: float = 0.3) -> str:
        """不可靠操作 - 带重试"""
        import random
        if random.random() < success_rate:
            return "操作成功"
        else:
            raise Exception("操作失败")
    
    @validation_decorator(lambda x: x > 0)
    def calculate_square(x: int) -> int:
        """计算平方 - 带验证"""
        return x * x
    
    print("\n1. 斐波那契数列（记忆化 + 计时）：")
    print(f"fibonacci(10) = {fibonacci(10)}")
    print(f"fibonacci(10) = {fibonacci(10)}")
    
    print("\n2. 不可靠操作（重试）：")
    try:
        result = unreliable_operation(0.8)
        print(f"结果: {result}")
    except Exception as e:
        print(f"最终失败: {e}")
    
    print("\n3. 参数验证：")
    try:
        print(f"calculate_square(5) = {calculate_square(5)}")
        print(f"calculate_square(-1) = {calculate_square(-1)}")
    except ValueError as e:
        print(f"验证失败: {e}")


def demonstrate_class_decorators():
    """
    演示类装饰器
    """
    print("\n=== 类装饰器演示 ===")
    
    @CounterDecorator
    def greet(name: str) -> str:
        """问候函数 - 带计数器"""
        return f"Hello, {name}!"
    
    # 测试计数器装饰器
    print("\n计数器装饰器测试：")
    for i in range(3):
        result = greet(f"用户{i+1}")
        print(f"调用结果: {result}")
    
    print(f"总调用次数: {greet.get_count()}")
    
    # 测试限流装饰器
    print("\n限流装饰器测试：")
    rate_limiter = RateLimitDecorator(max_calls=3, time_window=5.0)
    
    @rate_limiter
    def api_call(data: str) -> str:
        """API调用 - 带限流"""
        return f"处理数据: {data}"
    
    try:
        for i in range(5):
            result = api_call(f"数据{i+1}")
            print(f"API结果: {result}")
    except Exception as e:
        print(f"限流触发: {e}")


def demonstrate_decorator_chain():
    """
    演示装饰器链
    """
    print("\n=== 装饰器链演示 ===")
    
    def simple_function(x: int) -> int:
        """简单函数"""
        return x * 2
    
    # 创建装饰器链
    chain = DecoratorChain()
    chain.add_decorator(timing_decorator)
    chain.add_decorator(CounterDecorator)
    chain.add_decorator(memoize_decorator)
    
    # 应用装饰器链
    decorated_func = chain.decorate(simple_function)
    
    print("\n装饰器链测试：")
    for i in range(3):
        result = decorated_func(5)
        print(f"结果: {result}")
    
    print(f"调用次数: {decorated_func.get_count()}")


def demonstrate_real_world_usage():
    """
    演示实际应用场景
    """
    print("\n=== 实际应用场景演示 ===")
    
    service = UserService()
    
    print("\n1. 用户查询（缓存 + 计时）：")
    user1 = service.get_user(1)
    print(f"用户1: {user1}")
    user1_again = service.get_user(1)  # 应该命中缓存
    print(f"用户1（缓存）: {user1_again}")
    
    print("\n2. 用户列表（计数器）：")
    for i in range(3):
        users = service.list_users()
        print(f"用户数量: {len(users)}")
    print(f"list_users调用次数: {service.list_users.get_count()}")
    
    print("\n3. 邮件发送（限流）：")
    try:
        for i in range(7):
            success = service.send_email(1, f"消息{i+1}")
            print(f"邮件{i+1}发送: {'成功' if success else '失败'}")
    except Exception as e:
        print(f"限流触发: {e}")
    
    print("\n4. 用户删除（重试 + 验证）：")
    try:
        success = service.delete_user(2)
        print(f"删除用户2: {'成功' if success else '失败'}")
    except Exception as e:
        print(f"删除失败: {e}")


def demonstrate_java_comparison():
    """
    Java对比演示
    
    Java等价代码：
    ```java
    // Java版本的装饰器模式
    public interface Component {
        String operation();
        double getCost();
    }
    
    public class ConcreteComponent implements Component {
        private String name;
        private double baseCost;
        
        @Override
        public String operation() {
            return "基础组件: " + name;
        }
        
        @Override
        public double getCost() {
            return baseCost;
        }
    }
    
    public abstract class Decorator implements Component {
        protected Component component;
        
        public Decorator(Component component) {
            this.component = component;
        }
        
        @Override
        public String operation() {
            return component.operation();
        }
        
        @Override
        public double getCost() {
            return component.getCost();
        }
    }
    
    public class LoggingDecorator extends Decorator {
        public LoggingDecorator(Component component) {
            super(component);
        }
        
        @Override
        public String operation() {
            String result = super.operation();
            System.out.println("[LOG] " + result);
            return result + " + 日志记录";
        }
        
        @Override
        public double getCost() {
            return super.getCost() + 2.0;
        }
    }
    
    // Java没有内置的装饰器语法
    // 需要使用注解 + AOP框架（如Spring）实现类似功能
    ```
    
    Python优势：
    1. 内置装饰器语法(@decorator)
    2. 支持函数和类装饰器
    3. 动态装饰器组合
    4. 参数化装饰器更简洁
    """
    print("\n=== Java对比说明 ===")
    print("\nPython优势：")
    print("1. 内置@装饰器语法")
    print("2. 支持函数和类装饰器")
    print("3. 动态装饰器组合")
    print("4. 参数化装饰器简洁")
    print("5. 闭包支持状态保持")
    
    print("\nJava特点：")
    print("1. 需要定义接口和装饰器类")
    print("2. 使用注解 + AOP实现类似功能")
    print("3. 编译时类型检查更严格")
    print("4. Spring框架提供装饰器支持")


def performance_comparison():
    """
    性能对比测试
    """
    import time
    
    print("\n=== 性能对比 ===")
    
    # 原始函数
    def original_func(x: int) -> int:
        return x * x
    
    # 装饰后的函数
    @timing_decorator
    @memoize_decorator
    def decorated_func(x: int) -> int:
        return x * x
    
    # 传统装饰器模式
    component = ConcreteComponent("测试", 1.0)
    decorated_component = LoggingDecorator(
        EncryptionDecorator(
            CompressionDecorator(component)
        )
    )
    
    # 测试原始函数
    start_time = time.time()
    for i in range(10000):
        result = original_func(i)
    original_time = time.time() - start_time
    
    # 测试装饰后的函数
    start_time = time.time()
    for i in range(10000):
        result = decorated_func(i)
    decorated_time = time.time() - start_time
    
    # 测试传统装饰器
    start_time = time.time()
    for i in range(1000):  # 较少次数，因为有打印输出
        result = decorated_component.operation()
    traditional_time = time.time() - start_time
    
    print(f"原始函数 (10000次): {original_time:.4f}秒")
    print(f"Python装饰器 (10000次): {decorated_time:.4f}秒")
    print(f"传统装饰器 (1000次): {traditional_time:.4f}秒")
    print(f"装饰器开销: {(decorated_time - original_time) / original_time * 100:.2f}%")


if __name__ == "__main__":
    demonstrate_traditional_decorator()
    demonstrate_python_decorators()
    demonstrate_class_decorators()
    demonstrate_decorator_chain()
    demonstrate_real_world_usage()
    demonstrate_java_comparison()
    performance_comparison()